package com.work.order.service;

import com.work.order.feign.AccountFeignClient;
import com.work.order.feign.StorageFeignClient;
import com.work.order.model.Order;
import com.work.order.repository.OrderDAO;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.UUID;

@Slf4j
@Service
public class OrderService {

    @Resource
    private AccountFeignClient accountFeignClient;
    @Resource
    private StorageFeignClient storageFeignClient;
    @Resource
    private OrderDAO orderDAO;

    @Resource
    private TccOrderService tccOrderService;


    /**
     * 下单：创建订单、减库存，涉及到两个服务
     *
     * @param userId
     * @param commodityCode
     * @param count
     */
    @GlobalTransactional
    public void placeOrder(String userId, String commodityCode, Integer count) {
        log.info("开始全局事务，XID = " + RootContext.getXID());
        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
        String orderNo = UUID.randomUUID().toString().replace("-", "");
        Order order = new Order()
                .setUserId(userId)
                .setCommodityCode(commodityCode)
                .setCount(count).setOrderNo(orderNo)
                .setMoney(orderMoney);
        orderDAO.insert(order);

        storageFeignClient.deduct(commodityCode, count);

    }

//    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional
    public void create(String userId, String commodityCode, Integer count) {

        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
        String orderNo = UUID.randomUUID().toString().replace("-", "");

        Order order = new Order()
                .setUserId(userId)
                .setCommodityCode(commodityCode)
                .setCount(count).setOrderNo(orderNo)
                .setMoney(orderMoney);
        orderDAO.insert(order); //创建 订单

        accountFeignClient.reduce(userId, orderMoney); //扣除金额
        storageFeignClient.deduct(commodityCode,count); //扣除库存

        if (commodityCode.equals("product-2")) {
            throw new RuntimeException("异常:模拟业务异常:order branch exception");
        }

//        Order order1 = orderDAO.selectById(order.getId()); //查询 确定是否能查询到数据，当前隔离级别是 可重复读
        //修改 订单状态
//        Order order1 = new Order();
//        order1.setId(order.getId());
//        order1.setStatus(1);
//        orderDAO.updateById( order1 );

        //做一些抛异常操作，模拟回滚
        if (userId.equals("2")) {
            throw new RuntimeException("异常:模拟业务异常:order branch exception");
        }
    }


    /**
     * TCC 操作入口 TM
     * @param userId
     * @param commodityCode
     * @param count
     */
    @GlobalTransactional
    public void orderTccAction(String userId, String commodityCode, Integer count){
        log.info("########### 开始全局事务，XID = " + RootContext.getXID());
        //创建订单
        String orderNo = UUID.randomUUID().toString().replace("-", "");
        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));

        BusinessActionContext context = new BusinessActionContext();
        //创建订单
        Order order = new Order()
                .setUserId(userId)
                .setCommodityCode(commodityCode)
                .setCount(count)
                .setOrderNo(orderNo)
                .setMoney(orderMoney);
        tccOrderService.prepare(context, order);

        //扣减库存
        storageFeignClient.tccDeduct(commodityCode, count);

        //扣除用户金额
        accountFeignClient.tccReduce(userId, orderMoney);


//        System.out.println("其它业务逻辑 ");
        if (userId.equals("2")){
            throw new RuntimeException("异常:模拟业务异常: orderTccAction exception");
        }

    }



}
